<template>
  <div class="music-player" :class="{ 'expanded': isExpanded, 'playing': isPlaying }">
    <!-- Three.js Canvas for Visualization -->
    <canvas ref="visualCanvas" class="visualization-canvas"></canvas>
    
    <!-- Player Container -->
    <div class="player-container">
      <!-- Compact Mode -->
      <div class="player-compact" v-if="!isExpanded">
        <div class="song-info">
          <div class="album-art">
            <img :src="currentSong.cover" :alt="currentSong.title" />
            <div class="play-pulse" v-if="isPlaying"></div>
          </div>
          <div class="song-details">
            <div class="song-title">{{ currentSong.title }}</div>
            <div class="song-artist">{{ currentSong.artist }}</div>
          </div>
        </div>
        
        <div class="player-controls-compact">
          <button class="control-btn" @click="togglePlay">
            <i :class="isPlaying ? 'fas fa-pause' : 'fas fa-play'"></i>
          </button>
          <button class="expand-btn" @click="toggleExpanded">
            <i class="fas fa-chevron-up"></i>
          </button>
        </div>
      </div>
      
      <!-- Expanded Mode -->
      <div class="player-expanded" v-else>
        <div class="player-header">
          <h3>{{ currentSong.title }}</h3>
          <button class="close-btn" @click="toggleExpanded">
            <i class="fas fa-chevron-down"></i>
          </button>
        </div>
        
        <div class="player-content">
          <div class="album-section">
            <div class="album-art-large">
              <img :src="currentSong.cover" :alt="currentSong.title" />
              <div class="vinyl-effect" v-if="isPlaying"></div>
            </div>
            <div class="song-meta">
              <h4>{{ currentSong.title }}</h4>
              <p>{{ currentSong.artist }}</p>
              <p class="album">{{ currentSong.album }}</p>
            </div>
          </div>
          
          <div class="progress-section">
            <div class="time-display">
              <span>{{ formatTime(currentTime) }}</span>
              <span>{{ formatTime(duration) }}</span>
            </div>
            <div class="progress-bar" @click="seek">
              <div class="progress-fill" :style="{ width: progressPercent + '%' }"></div>
              <div class="progress-handle" :style="{ left: progressPercent + '%' }"></div>
            </div>
          </div>
          
          <div class="player-controls">
            <button class="control-btn" @click="previousTrack" :disabled="!hasPrevious">
              <i class="fas fa-step-backward"></i>
            </button>
            <button class="control-btn play-btn" @click="togglePlay">
              <i :class="isPlaying ? 'fas fa-pause' : 'fas fa-play'"></i>
            </button>
            <button class="control-btn" @click="nextTrack" :disabled="!hasNext">
              <i class="fas fa-step-forward"></i>
            </button>
          </div>
          
          <div class="volume-section">
            <i class="fas fa-volume-down"></i>
            <input 
              type="range" 
              min="0" 
              max="100" 
              v-model="volume" 
              @input="setVolume"
              class="volume-slider"
            >
            <i class="fas fa-volume-up"></i>
          </div>
        </div>
      </div>
    </div>
    
    <!-- Audio Element -->
    <audio 
      ref="audioPlayer"
      @loadedmetadata="onLoadedMetadata"
      @timeupdate="onTimeUpdate"
      @ended="onSongEnd"
      @play="onPlay"
      @pause="onPause"
    ></audio>
  </div>
</template>

<script>
import * as THREE from 'three'
import { markRaw } from 'vue'

export default {
  name: 'MusicPlayer',
  data() {
    return {
      isExpanded: false,
      isPlaying: false,
      currentTime: 0,
      duration: 0,
      volume: 70,
      currentSongIndex: 0,
      playlist: [
        {
          title: 'Håll om mig',
          artist: 'Nanne',
          album: 'Single',
          src: require('../assets/Håll om mig - Nanne.mp3'),
          cover: require('../assets/img/albums/1.jpg')
        }
      ]
    }
  },
  computed: {
    currentSong() {
      return this.playlist[this.currentSongIndex] || this.playlist[0]
    },
    progressPercent() {
      if (this.duration === 0) return 0
      return (this.currentTime / this.duration) * 100
    },
    hasPrevious() {
      return this.currentSongIndex > 0
    },
    hasNext() {
      return this.currentSongIndex < this.playlist.length - 1
    }
  },
  mounted() {
    // 初始化Three.js对象 (使用markRaw避免响应式包装)
    this.threeObjects = markRaw({
      scene: null,
      camera: null,
      renderer: null,
      analyser: null,
      audioContext: null,
      dataArray: null,
      bufferLength: 0,
      visualElements: [],
      animationId: null
    })
    
    this.initPlayer()
    this.initVisualization()
    this.loadCurrentSong()
    
    // 全局播放控制
    window.musicPlayer = this
  },
  beforeUnmount() {
    if (this.threeObjects?.animationId) {
      cancelAnimationFrame(this.threeObjects.animationId)
    }
    if (this.threeObjects?.renderer) {
      this.threeObjects.renderer.dispose()
    }
    if (this.threeObjects?.audioContext) {
      this.threeObjects.audioContext.close()
    }
  },
  methods: {
    initPlayer() {
      this.$nextTick(() => {
        if (this.$refs.audioPlayer) {
          this.$refs.audioPlayer.volume = this.volume / 100
        }
      })
    },
    
    initVisualization() {
      this.$nextTick(() => {
        try {
          if (!this.$refs.visualCanvas || !this.threeObjects) return
          
          // Scene
          this.threeObjects.scene = markRaw(new THREE.Scene())
          
          // Camera
          this.threeObjects.camera = markRaw(new THREE.PerspectiveCamera(75, 400 / 100, 0.1, 1000))
          this.threeObjects.camera.position.z = 5
          
          // Renderer
          this.threeObjects.renderer = markRaw(new THREE.WebGLRenderer({
            canvas: this.$refs.visualCanvas,
            alpha: true,
            antialias: true
          }))
          this.threeObjects.renderer.setSize(400, 100)
          this.threeObjects.renderer.setClearColor(0x000000, 0)
          
          // Create visualization elements
          this.createVisualizationElements()
          
          // Start animation loop
          this.animate()
          
        } catch (error) {
          console.error('Visualization initialization error:', error)
        }
      })
    },
    
    createVisualizationElements() {
      if (!this.threeObjects?.scene) return
      
      // Create audio bars
      const barCount = 32
      const barWidth = 0.15
      const barSpacing = 0.2
      
      this.threeObjects.visualElements = []
      
      for (let i = 0; i < barCount; i++) {
        const geometry = markRaw(new THREE.BoxGeometry(barWidth, 0.1, 0.1))
        const material = markRaw(new THREE.MeshBasicMaterial({
          color: new THREE.Color().setHSL((i / barCount) * 0.7 + 0.15, 0.8, 0.6)
        }))
        const bar = markRaw(new THREE.Mesh(geometry, material))
        
        bar.position.x = (i - barCount / 2) * barSpacing
        bar.position.y = 0
        
        this.threeObjects.visualElements.push(bar)
        this.threeObjects.scene.add(bar)
      }
    },
    
    animate() {
      if (!this.threeObjects?.renderer || !this.threeObjects?.scene || !this.threeObjects?.camera) {
        return
      }
      
      this.threeObjects.animationId = requestAnimationFrame(this.animate)
      
      try {
        // Update visualization based on audio
        if (this.threeObjects.analyser && this.threeObjects.dataArray && this.isPlaying) {
          this.threeObjects.analyser.getByteFrequencyData(this.threeObjects.dataArray)
          
          this.threeObjects.visualElements.forEach((bar, index) => {
            const dataIndex = Math.floor((index / this.threeObjects.visualElements.length) * this.threeObjects.bufferLength)
            const value = this.threeObjects.dataArray[dataIndex] / 255
            
            bar.scale.y = Math.max(0.1, value * 3)
            bar.material.color.setHSL((value * 0.3) + 0.15, 0.8, 0.6)
          })
        } else {
          // Idle animation when not playing
          const time = Date.now() * 0.001
          this.threeObjects.visualElements.forEach((bar, index) => {
            bar.scale.y = 0.1 + Math.sin(time + index * 0.5) * 0.05
          })
        }
        
        this.threeObjects.renderer.render(this.threeObjects.scene, this.threeObjects.camera)
      } catch (error) {
        console.error('Animation error:', error)
        // 停止动画循环以防止错误重复
        if (this.threeObjects?.animationId) {
          cancelAnimationFrame(this.threeObjects.animationId)
          this.threeObjects.animationId = null
        }
      }
    },
    
    async setupAudioContext() {
      try {
        if (!this.threeObjects) return
        
        if (!this.threeObjects.audioContext) {
          this.threeObjects.audioContext = markRaw(new (window.AudioContext || window.webkitAudioContext)())
          this.threeObjects.analyser = markRaw(this.threeObjects.audioContext.createAnalyser())
          this.threeObjects.analyser.fftSize = 128
          this.threeObjects.bufferLength = this.threeObjects.analyser.frequencyBinCount
          this.threeObjects.dataArray = new Uint8Array(this.threeObjects.bufferLength)
          
          const source = this.threeObjects.audioContext.createMediaElementSource(this.$refs.audioPlayer)
          source.connect(this.threeObjects.analyser)
          this.threeObjects.analyser.connect(this.threeObjects.audioContext.destination)
        }
        
        if (this.threeObjects.audioContext.state === 'suspended') {
          await this.threeObjects.audioContext.resume()
        }
      } catch (error) {
        console.error('Audio context setup error:', error)
      }
    },
    
    loadCurrentSong() {
      if (this.$refs.audioPlayer && this.currentSong) {
        this.$refs.audioPlayer.src = this.currentSong.src
        this.$refs.audioPlayer.load()
      }
    },
    
    async togglePlay() {
      try {
        if (!this.$refs.audioPlayer) return
        
        await this.setupAudioContext()
        
        if (this.isPlaying) {
          this.$refs.audioPlayer.pause()
        } else {
          await this.$refs.audioPlayer.play()
        }
      } catch (error) {
        console.error('Play error:', error)
      }
    },
    
    playNewSong(songData) {
      // 停止当前播放
      if (this.isPlaying) {
        this.$refs.audioPlayer.pause()
      }
      
      // 添加新歌曲到播放列表（如果不存在）
      const existingIndex = this.playlist.findIndex(song => song.src === songData.src)
      if (existingIndex >= 0) {
        this.currentSongIndex = existingIndex
      } else {
        this.playlist.push(songData)
        this.currentSongIndex = this.playlist.length - 1
      }
      
      // 加载并播放新歌曲
      this.loadCurrentSong()
      this.$nextTick(() => {
        this.togglePlay()
      })
    },
    
    previousTrack() {
      if (this.hasPrevious) {
        this.currentSongIndex--
        this.loadCurrentSong()
        if (this.isPlaying) {
          this.$nextTick(() => this.togglePlay())
        }
      }
    },
    
    nextTrack() {
      if (this.hasNext) {
        this.currentSongIndex++
        this.loadCurrentSong()
        if (this.isPlaying) {
          this.$nextTick(() => this.togglePlay())
        }
      }
    },
    
    seek(event) {
      if (!this.$refs.audioPlayer || this.duration === 0) return
      
      const rect = event.target.getBoundingClientRect()
      const clickX = event.clientX - rect.left
      const percent = clickX / rect.width
      const seekTime = percent * this.duration
      
      this.$refs.audioPlayer.currentTime = seekTime
    },
    
    setVolume() {
      if (this.$refs.audioPlayer) {
        this.$refs.audioPlayer.volume = this.volume / 100
      }
    },
    
    toggleExpanded() {
      this.isExpanded = !this.isExpanded
    },
    
    formatTime(seconds) {
      if (isNaN(seconds)) return '0:00'
      const mins = Math.floor(seconds / 60)
      const secs = Math.floor(seconds % 60)
      return `${mins}:${secs.toString().padStart(2, '0')}`
    },
    
    // Audio Events
    onLoadedMetadata() {
      this.duration = this.$refs.audioPlayer.duration
    },
    
    onTimeUpdate() {
      this.currentTime = this.$refs.audioPlayer.currentTime
    },
    
    onPlay() {
      this.isPlaying = true
    },
    
    onPause() {
      this.isPlaying = false
    },
    
    onSongEnd() {
      if (this.hasNext) {
        this.nextTrack()
      } else {
        this.isPlaying = false
      }
    }
  }
}
</script>

<style scoped>
.music-player {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(10, 10, 10, 0.95);
  backdrop-filter: blur(20px);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  z-index: 999;
  transition: all 0.3s ease;
  height: 80px;
}

.music-player.expanded {
  height: 400px;
}

.visualization-canvas {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 400px;
  height: 100px;
  opacity: 0.7;
  pointer-events: none;
}

.player-container {
  position: relative;
  height: 100%;
  padding: 0 20px;
}

/* Compact Mode */
.player-compact {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 80px;
  padding: 0 20px;
}

.song-info {
  display: flex;
  align-items: center;
  gap: 15px;
}

.album-art {
  position: relative;
  width: 50px;
  height: 50px;
  border-radius: 8px;
  overflow: hidden;
}

.album-art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.play-pulse {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(78, 205, 196, 0.3);
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 0.7; }
}

.song-details {
  color: white;
}

.song-title {
  font-weight: 600;
  font-size: 0.9rem;
  margin-bottom: 2px;
}

.song-artist {
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.8rem;
}

.player-controls-compact {
  display: flex;
  align-items: center;
  gap: 15px;
}

.control-btn {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.1);
  border: none;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s ease;
}

.control-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: scale(1.1);
}

.control-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.expand-btn {
  background: linear-gradient(135deg, #ff6b6b, #4ecdc4);
}

/* Expanded Mode */
.player-expanded {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 20px;
}

.player-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.player-header h3 {
  color: white;
  margin: 0;
  font-size: 1.2rem;
}

.close-btn {
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.7);
  font-size: 1.5rem;
  cursor: pointer;
  transition: color 0.3s ease;
}

.close-btn:hover {
  color: white;
}

.player-content {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 2fr;
  gap: 30px;
  align-items: center;
}

.album-section {
  text-align: center;
}

.album-art-large {
  position: relative;
  width: 150px;
  height: 150px;
  margin: 0 auto 20px;
  border-radius: 15px;
  overflow: hidden;
}

.album-art-large img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.vinyl-effect {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: radial-gradient(circle, transparent 40%, rgba(0,0,0,0.3) 41%, rgba(0,0,0,0.3) 42%, transparent 43%);
  animation: spin 3s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

.song-meta h4 {
  color: white;
  margin: 0 0 5px 0;
  font-size: 1.1rem;
}

.song-meta p {
  color: rgba(255, 255, 255, 0.7);
  margin: 0 0 3px 0;
  font-size: 0.9rem;
}

.song-meta .album {
  font-size: 0.8rem;
  opacity: 0.6;
}

.progress-section {
  margin-bottom: 20px;
}

.time-display {
  display: flex;
  justify-content: space-between;
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.8rem;
  margin-bottom: 10px;
}

.progress-bar {
  position: relative;
  height: 6px;
  background: rgba(255, 255, 255, 0.2);
  border-radius: 3px;
  cursor: pointer;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
  border-radius: 3px;
  transition: width 0.1s linear;
}

.progress-handle {
  position: absolute;
  top: -4px;
  width: 14px;
  height: 14px;
  background: white;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0,0,0,0.3);
  transform: translateX(-50%);
  transition: left 0.1s linear;
}

.player-controls {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-bottom: 20px;
}

.play-btn {
  width: 60px;
  height: 60px;
  background: linear-gradient(135deg, #ff6b6b, #4ecdc4);
  font-size: 1.5rem;
}

.volume-section {
  display: flex;
  align-items: center;
  gap: 15px;
  color: rgba(255, 255, 255, 0.7);
}

.volume-slider {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.2);
  outline: none;
  cursor: pointer;
}

.volume-slider::-webkit-slider-thumb {
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #4ecdc4;
  cursor: pointer;
}

/* Responsive */
@media (max-width: 768px) {
  .player-content {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  
  .player-compact {
    padding: 0 15px;
  }
  
  .song-info {
    gap: 10px;
  }
  
  .album-art {
    width: 40px;
    height: 40px;
  }
}
</style>
